﻿using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Repositories;
using SelfMadeMillionaire.Core.Specifications;
using SelfMadeMillionaire.DAL;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace SelfMadeMillionaire.DAL.Repositories
{
	public abstract class Repository<T> : IRepository<T> where T : BaseEntity
	{
		protected IUnitOfWork _uow;
		protected IDbSet<T> _dbSet;
		public Repository(IUnitOfWork unitOfWork)
		{
			_uow = unitOfWork;
			_dbSet = _uow.GetDbSet<T>();
		}

		public T Get(int id)
		{
			return _dbSet.SingleOrDefault(x => x.ID == id);
		}

        public T Get(Expression<Func<T, bool>> predicate)
        {
            return _dbSet.FirstOrDefault(predicate);
        }

		public IEnumerable<T> GetAll()
		{
			return _dbSet;
		}

        public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate)
        {
            return _dbSet.Where(predicate);
        }

        public IQueryable<T> GetAsQuery()
        {
            return _dbSet;
        }

		public T Add(T entity)
		{
			var addedEntity = _dbSet.Add(entity);
			_uow.Commit();

			return addedEntity;
		}

		public virtual void Remove(int id)
		{
			_dbSet.Remove(Get(id));
			_uow.Commit();
		}


		public virtual T Update(T entity)
		{
			var dbEntity = Get(entity.ID);
			dbEntity = entity;

			_uow.Commit();

			return dbEntity;
		}



		public IEnumerable<T> GetList(ISearchSpecification<T> specification)
		{
			return specification.SatisfiedBy(_dbSet);
		}

		public void Commit()
		{
			_uow.Commit();
		}
	}

}
